<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>每日清单</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <!-- 添加SheetJS库用于Excel导出 -->
    <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>
    <style>
      body {
        font-family: Arial, sans-serif;
        margin: 20px;
      }
      table {
        border-collapse: collapse;
        width: 100%;
        margin-top: 10px;
      }
      th,
      td {
        border: 1px solid black;
        padding: 8px;
        text-align: center;
      }
      th {
        background-color: #f2f2f2;
      }
      .date-input {
        width: 90%;
        padding: 5px;
        box-sizing: border-box;
        text-align: center;
      }
      .item-input {
        width: 90%;
        padding: 5px;
        box-sizing: border-box;
        text-align: center;
      }
      .price-input {
        width: 50%; /* 价格输入框宽度为项目输入框的三分之一 */
        padding: 2px;
        box-sizing: border-box;
        text-align: center;
      }
      .borderless-input {
        border: none;
        outline: none;
        background: transparent;
      }
      .checkbox-container {
        display: flex;
        align-items: center;
        margin-bottom: 10px;
      }
      .checkbox-container label {
        margin-left: 5px;
        font-weight: bold;
        color: #8b4513;
      }
      .total-container {
        margin-top: 20px;
        font-weight: bold;
        font-size: 18px;
      }
      .daily-total {
        color: blue;
        font-weight: bold;
      }
      .daily-balance {
        color: red;
        font-weight: bold;
      }
      .grand-total {
        color: #8b4513;
        font-weight: bold;
      }
      .action-buttons {
        margin-top: 15px;
        display: flex;
        gap: 10px;
      }
      button {
        padding: 8px 15px;
        background-color: #4caf50;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
      }
      button:hover {
        background-color: #45a049;
      }
      .clear-btn {
        background-color: #f44336;
      }
      .clear-btn:hover {
        background-color: #d32f2f;
      }
      .export-btn {
        background-color: #2196F3;
      }
      .export-btn:hover {
        background-color: #0b7dda;
      }
      /* 调整表格列宽度 */
      table th:nth-child(4),
      table th:nth-child(6),
      table th:nth-child(8),
      table th:nth-child(10) {
        width: 13%; /* 项目列宽度 */
      }
      table th:nth-child(2) {
        width: 7.4%;
      }
      table th:nth-child(3),
      table th:nth-child(5),
      table th:nth-child(7),
      table th:nth-child(9),
      table th:nth-child(11) {
        width: 5%; /* 价格列宽度*/
      }
      #h1{
        color: red;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <h1>2025年<span id="h1">8</span>月每日清单</h1>
      <div class="checkbox-container">
        <input
          type="checkbox"
          id="selectAll"
          v-model="selectAll"
          @change="toggleSelectAll"
        />
        <label for="selectAll">全选</label>
      </div>

      <table id="dailyListTable">
        <thead>
          <tr>
            <th></th>
            <th>日期：</th>
            <th>今日额度：</th>
            <th>早上干了什么：</th>
            <th>花费多少钱：</th>
            <th>中午干了什么：</th>
            <th>花费多少钱：</th>
            <th>下午干了什么：</th>
            <th>花费多少钱：</th>
            <th>晚上干了什么：</th>
            <th>花费多少钱：</th>
            <th class="daily-total">今日小计</th>
            <th class="daily-balance">今日余额</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(row, index) in rows" :key="index">
            <td>
              <input
                type="checkbox"
                v-model="row.selected"
                @change="calculateTotal"
              />
            </td>
            <td>
              <input
                type="text"
                class="date-input"
                v-model="row.date"
                @keyup.enter="addNewRow"
                @keyup.delete="handleDeleteKeyPress(index)"
                @input="saveData"
                ref="dateInput"
              />
            </td>
            <td>
              <div
                style="
                  display: flex;
                  align-items: center;
                  justify-content: center;
                "
              >
                <input
                  type="number"
                  class="price-input borderless-input"
                  v-model="row.dailyBudget"
                  @change="calculateDailyBalance(index)"
                  @input="saveData"
                />
                <span>元</span>
              </div>
            </td>
            <td>
              <input
                type="text"
                class="item-input"
                v-model="row.items[0].name"
                @input="saveData"
              />
            </td>
            <td>
              <div
                style="
                  display: flex;
                  align-items: center;
                  justify-content: center;
                "
              >
                <input
                  type="number"
                  class="price-input borderless-input"
                  v-model="row.items[0].price"
                  @change="calculateDailyTotal(index)"
                  @input="saveData"
                />
                <span>元</span>
              </div>
            </td>
            <td>
              <input
                type="text"
                class="item-input"
                v-model="row.items[1].name"
                @input="saveData"
              />
            </td>
            <td>
              <div
                style="
                  display: flex;
                  align-items: center;
                  justify-content: center;
                "
              >
                <input
                  type="number"
                  class="price-input borderless-input"
                  v-model="row.items[1].price"
                  @change="calculateDailyTotal(index)"
                  @input="saveData"
                />
                <span>元</span>
              </div>
            </td>
            <td>
              <input
                type="text"
                class="item-input"
                v-model="row.items[2].name"
                @input="saveData"
              />
            </td>
            <td>
              <div
                style="
                  display: flex;
                  align-items: center;
                  justify-content: center;
                "
              >
                <input
                  type="number"
                  class="price-input borderless-input"
                  v-model="row.items[2].price"
                  @change="calculateDailyTotal(index)"
                  @input="saveData"
                />
                <span>元</span>
              </div>
            </td>
            <td>
              <input
                type="text"
                class="item-input"
                v-model="row.items[3].name"
                @input="saveData"
              />
            </td>
            <td>
              <div
                style="
                  display: flex;
                  align-items: center;
                  justify-content: center;
                "
              >
                <input
                  type="number"
                  class="price-input borderless-input"
                  v-model="row.items[3].price"
                  @change="calculateDailyTotal(index)"
                  @input="saveData"
                />
                <span>元</span>
              </div>
            </td>
            <td class="daily-sum" style="color: blue;">{{ row.dailySum.toFixed(2) }}元</td>
            <td class="daily-balance">{{ calculateBalance(index) }}元</td>
          </tr>
        </tbody>
      </table>

      <div class="total-container">
        <span>总共消费：</span>
        <span id="grandTotal" class="grand-total"
          >{{ grandTotal.toFixed(2) }}元</span
        >
        <span style="margin-left: 20px">总余额：</span>
        <span id="grandBalance" class="daily-balance"
          >{{ grandBalance.toFixed(2) }}元</span
        >
        <span style="margin-left: 20px">总额度还剩下：</span>
        <span id="grandBudgetRemaining" class="grand-total"
          >{{ grandBudgetRemaining.toFixed(2) }}元</span
        >
      </div>

      <div class="action-buttons">
        <button @click="clearData" class="clear-btn">清除所有数据</button>
      </div>
    </div>

    <script>
      new Vue({
        el: "#app",
        data() {
          return {
            selectAll: false,
            rows: [],
            grandTotal: 0,
            grandBalance: 0,
            grandBudgetRemaining: 4000,
          };
        },
        methods: {
          // 创建新行的数据结构
          createEmptyRow() {
            return {
              selected: false, // 默认不选中
              date: "",
              dailyBudget: 0,
              items: [
                { name: "", price: 0 },
                { name: "", price: 0 },
                { name: "", price: 0 },
                { name: "", price: 0 },
              ],
              dailySum: 0,
            };
          },

          // 计算今日余额
          calculateBalance(index) {
            const row = this.rows[index];
            const budget = parseFloat(row.dailyBudget) || 0;
            const sum = parseFloat(row.dailySum) || 0;
            return (budget - sum).toFixed(2);
          },

          // 更新今日余额
          calculateDailyBalance(index) {
            this.saveData();
          },

          // 添加新行
          addNewRow() {
            this.rows.push(this.createEmptyRow());
            // 在下一个渲染周期后聚焦到新行的日期输入框
            this.$nextTick(() => {
              const lastIndex = this.rows.length - 1;
              if (this.$refs.dateInput && this.$refs.dateInput[lastIndex]) {
                this.$refs.dateInput[lastIndex].focus();
              }
            });
            this.saveData();
          },

          // 计算单行的日小计
          calculateDailyTotal(index) {
            const row = this.rows[index];
            let sum = 0;

            row.items.forEach((item) => {
              sum += parseFloat(item.price) || 0;
            });

            row.dailySum = sum;
            this.calculateTotal();
            this.saveData();
          },

          // 全选/取消全选
          toggleSelectAll() {
            this.rows.forEach((row) => {
              row.selected = this.selectAll;
            });
            this.calculateTotal();
            this.saveData();
          },

          // 计算总计（勾选项的日小计总和和余额总和）
          calculateTotal() {
            let total = 0;
            let balanceTotal = 0;
            let totalBudget = 0;

            this.rows.forEach((row, index) => {
              // 计算所有行的今日额度总和，无论是否选中
              totalBudget += parseFloat(row.dailyBudget) || 0;

              if (row.selected) {
                total += row.dailySum;

                // 计算该行的余额并累加到总余额
                const budget = parseFloat(row.dailyBudget) || 0;
                const sum = parseFloat(row.dailySum) || 0;
                balanceTotal += budget - sum;
              }
            });

            this.grandTotal = total;
            this.grandBalance = balanceTotal;
            // 计算总额度：默认4000减去所有今日额度的和
            this.grandBudgetRemaining = 4000 - totalBudget;

            // 检查是否所有行都被选中
            this.selectAll =
              this.rows.length > 0 && this.rows.every((row) => row.selected);
          },

          // 保存数据到本地存储
          saveData() {
            try {
              // 确保每行的selected状态也被保存
              const rowsToSave = this.rows.map((row) => {
                return {
                  ...row,
                  selected: row.selected || false, // 确保selected属性存在
                };
              });

              localStorage.setItem("dailyListData", JSON.stringify(rowsToSave));
              localStorage.setItem("dailyListGrandTotal", this.grandTotal);
              localStorage.setItem("dailyListGrandBalance", this.grandBalance);
              localStorage.setItem("dailyListSelectAll", this.selectAll);
              localStorage.setItem(
                "dailyListGrandBudgetRemaining",
                this.grandBudgetRemaining
              );
            } catch (e) {
              console.error("保存数据到本地存储失败:", e);
            }
          },

          // 从本地存储加载数据
          loadData() {
            try {
              const savedRows = localStorage.getItem("dailyListData");
              const savedGrandTotal = localStorage.getItem(
                "dailyListGrandTotal"
              );
              const savedGrandBalance = localStorage.getItem(
                "dailyListGrandBalance"
              );
              const savedSelectAll = localStorage.getItem("dailyListSelectAll");
              const savedGrandBudgetRemaining = localStorage.getItem(
                "dailyListGrandBudgetRemaining"
              );

              if (savedRows) {
                this.rows = JSON.parse(savedRows);
                // 确保每行都有必要的属性
                this.rows.forEach((row, index) => {
                  if (row.dailySum === undefined) {
                    this.calculateDailyTotal(index);
                  }
                  // 确保每行都有dailyBudget属性
                  if (row.dailyBudget === undefined) {
                    row.dailyBudget = 0;
                  }
                  // 确保每行都有selected属性
                  if (row.selected === undefined) {
                    row.selected = false;
                  }

                  // 确保每行都有4个items
                  if (row.items && row.items.length < 4) {
                    while (row.items.length < 4) {
                      row.items.push({ name: "", price: 0 });
                    }
                  }
                });
              } else {
                // 如果没有保存的数据，创建两个空行
                this.rows = [this.createEmptyRow(), this.createEmptyRow()];
              }

              if (savedGrandTotal) {
                this.grandTotal = parseFloat(savedGrandTotal);
              }

              if (savedGrandBalance) {
                this.grandBalance = parseFloat(savedGrandBalance);
              }

              if (savedSelectAll) {
                this.selectAll = savedSelectAll === "true";
              }

              if (savedGrandBudgetRemaining) {
                this.grandBudgetRemaining = parseFloat(
                  savedGrandBudgetRemaining
                );
              }
            } catch (e) {
              console.error("从本地存储加载数据失败:", e);
              // 出错时创建两个空行
              this.rows = [this.createEmptyRow(), this.createEmptyRow()];
            }
          },

          // 处理删除键按下事件
          handleDeleteKeyPress(index) {
            // 只有当日期输入框为空时才触发删除功能
            if (!this.rows[index].date || this.rows[index].date.trim() === '') {
              if (confirm("确定要删除这一行吗？")) {
                this.rows.splice(index, 1);

                // 如果删除后没有行了，添加一个空行
                if (this.rows.length === 0) {
                  this.rows.push(this.createEmptyRow());
                }

                this.calculateTotal();
                this.saveData();
              }
            }
            // 如果输入框不为空，不执行任何操作
          },

          // 删除指定行
          deleteRow(index) {
            if (confirm("确定要删除这一行吗？")) {
              this.rows.splice(index, 1);

              // 如果删除后没有行了，添加一个空行
              if (this.rows.length === 0) {
                this.rows.push(this.createEmptyRow());
              }

              this.calculateTotal();
              this.saveData();
            }
          },

          // 清除所有数据
          clearData() {
            if (confirm("确定要清除所有数据吗？此操作不可恢复。")) {
              localStorage.removeItem("dailyListData");
              localStorage.removeItem("dailyListGrandTotal");
              localStorage.removeItem("dailyListGrandBalance");
              localStorage.removeItem("dailyListSelectAll");
              localStorage.removeItem("dailyListGrandBudgetRemaining");

              this.rows = [this.createEmptyRow(), this.createEmptyRow()];
              this.selectAll = false;
              this.grandTotal = 0;
              this.grandBalance = 0;
              this.grandBudgetRemaining = 4000;
            }
          },

          // 导出数据到Excel
          exportToExcel() {
            try {
              // 创建工作簿
              const wb = XLSX.utils.book_new();
              
              // 准备数据
              const data = [
                // 表头
                [
                  "日期", "今日额度", 
                  "早上干了什么", "花费多少钱", 
                  "中午干了什么", "花费多少钱", 
                  "下午干了什么", "花费多少钱", 
                  "晚上干了什么", "花费多少钱", 
                  "今日小计", "今日余额"
                ]
              ];
              
              // 添加每一行数据
              this.rows.forEach(row => {
                data.push([
                  row.date,
                  parseFloat(row.dailyBudget) || 0,
                  row.items[0].name,
                  parseFloat(row.items[0].price) || 0,
                  row.items[1].name,
                  parseFloat(row.items[1].price) || 0,
                  row.items[2].name,
                  parseFloat(row.items[2].price) || 0,
                  row.items[3].name,
                  parseFloat(row.items[3].price) || 0,
                  row.dailySum,
                  parseFloat(row.dailyBudget || 0) - parseFloat(row.dailySum || 0)
                ]);
              });
              
              // 添加总计行
              data.push([
                "总计", "", "", "", "", "", "", "", "", "",
                this.grandTotal, this.grandBalance
              ]);
              
              // 添加总额度剩余行
              data.push([
                "总额度剩余", this.grandBudgetRemaining, "", "", "", "", "", "", "", "", "", ""
              ]);
              
              // 创建工作表
              const ws = XLSX.utils.aoa_to_sheet(data);
              
              // 设置列宽
              const wscols = [
                {wch: 12}, // 日期
                {wch: 10}, // 今日额度
                {wch: 20}, // 早上干了什么
                {wch: 10}, // 花费多少钱
                {wch: 20}, // 中午干了什么
                {wch: 10}, // 花费多少钱
                {wch: 20}, // 下午干了什么
                {wch: 10}, // 花费多少钱
                {wch: 20}, // 晚上干了什么
                {wch: 10}, // 花费多少钱
                {wch: 10}, // 今日小计
                {wch: 10}  // 今日余额
              ];
              ws['!cols'] = wscols;
              
              // 将工作表添加到工作簿
              XLSX.utils.book_append_sheet(wb, ws, "每日清单");
              
              // 生成Excel文件并下载
              const fileName = `每日清单_${new Date().toLocaleDateString().replace(/\//g, '-')}.xlsx`;
              XLSX.writeFile(wb, fileName);
              
              alert("导出成功！文件已保存到下载文件夹。");
            } catch (e) {
              console.error("导出Excel失败:", e);
              alert("导出失败，请查看控制台获取详细错误信息。");
            }
          },
        },
        created() {
          // 从本地存储加载数据
          this.loadData();

          // 初始化时计算所有行的日小计
          this.rows.forEach((row, index) => {
            this.calculateDailyTotal(index);
          });
        },
      });
    </script>
  </body>
</html>